#include "lineraster.h"

LineRaster::LineRaster()
{

}


LineRaster::~LineRaster()
{

}


void LineRaster::rasterizeLine(std::vector<Point> &results,
                               const Point &v0,
                               const Point &v1)
{
    Point start = v0;
    Point end = v1;

    //1.保证x方向是从小到大的
    if(start.x > end.x)
    {
        Point temp = start;
        start = end;
        end = temp;
    }
    results.push_back(start);

    //2.保证斜率大于0(y方向也是从小到大)，如果需要翻转，必须记录
    bool flipY = false;
    if(start.y > end.y)
    {
       start.y *=  -1;
       end.y *=  -1;
       flipY = true;
    }

    //3.保证斜率在0-1之间，如果需要调整，必须重新记录
    int deltaX = end.x - start.x;
    int deltaY = end.y - start.y;

    bool swapXY = false;

    if(deltaX < deltaY)
    {
        std::swap(start.x, start.y);
        std::swap(end.x, end.y);
        std::swap(deltaX, deltaY);

        swapXY = true;
    }


    //4 brensenham
    int curX = start.x;
    int curY = start.y;

    int resX,resY;

    Point curPoint;

    int p = 2 * deltaY - deltaX;

    for(int i = start.x; i <= end.x;i++)
    {
        if(p >= 0)
        {
            curY += 1;
            p -= 2 * deltaX;
        }

        curX  += 1;
        p += 2 * deltaY;

        //处理新xy，flip and swap
        resX = curX;
        resY = curY;

        if(swapXY)
        {
            int temp = resX;
            resX = resY;
            resY = temp;
        }

        if(flipY)
        {
            resY *= -1;
        }

        //产生新顶点
        curPoint.x = resX;
        curPoint.y = resY;

        //颜色插值
        interpolantLine(start, end, curPoint);

        results.push_back(curPoint);
    }
}

void LineRaster::interpolantLine(const Point &v0, const Point &v1, Point &target)
{
    float weight = 0.0F;

    if (v1.x != v0.x)
    {
        //用x做比例
        weight = (float)(target.x - v0.x) / (float)(v1.x - v0.x);
    }
    else if (v1.y != v0.y) {
        //用y做比例
        weight = (float)(target.y - v0.y) / (float)(v1.y - v0.y);
    }

    if(weight > 1.0f)
    {
        weight = 1.0f;
    }

    Color result = lerpRGBA(v0.color, v1.color, weight);

    target.color = result;
}

